package com.mycity.controller;

import java.util.List;
import java.util.UUID;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.mycity.bean.Comment;
import com.mycity.bean.Post;
import com.mycity.bean.User;
import com.mycity.bean.Report;
import com.mycity.semantic.UserRelation;
import com.mycity.services.LoginService;
import com.mycity.services.ProfileService;
import com.mycity.services.RegistrationService;
import com.mycity.services.ReportService;


@Controller
@RequestMapping("/services/user")
public class UserController extends HelloController{

	private RegistrationService registrationService = new RegistrationService();
	private LoginService loginService = new LoginService();
	private ProfileService profileService = new ProfileService();
	private ReportService reportService = new ReportService();

	// get log4j handler
	private static final Logger LOGGER = Logger.getLogger(UserController.class);

	public void setLoginService(LoginService loginService) {
		this.loginService = loginService;
	}


	public void setRegistrationService(RegistrationService registrationService) {
		this.registrationService = registrationService;
	}

	@RequestMapping(method = RequestMethod.GET, value = "/login")
	public @ResponseBody User loginUser(String email, String password) throws Exception {
		User loggedinUser;
		try {
			loggedinUser = loginService.login(email, password);

			// Nullify the fields that need to be secure.
			loggedinUser.setPassword(null);
		} catch (Exception e) {
			LOGGER.error("The user cannot login : " + email, e);
			throw new Exception("Invalid username or password");
		} 

		return loggedinUser;


	}

	@RequestMapping(method = RequestMethod.GET, value = "/register")
	public @ResponseBody User registerUser(String username, String name, String surname, String email, String password) throws Exception {
		User loggedinUser;
		try {
			loggedinUser = registrationService.registerUser(username, name, surname, email, password);

			// Nullify the fields that need to be secure.
			loggedinUser.setPassword(null);
		} catch (Exception e) {
			LOGGER.error("The user cannot register : " + email, e);
			throw new Exception("Invalid username or password");
		} 

		return loggedinUser;


	}


	@RequestMapping(method = RequestMethod.GET, value = "/loginFailed")
	public @ResponseBody String loginFailed(String email, String password) throws Exception {

		return "Invalid username or password!";


	}

	@RequestMapping(method = RequestMethod.GET, value = "/showAllPosts")
	public @ResponseBody List<Post> showAllPosts(int userId) throws Exception {

		List<Post> postList;
		try {
			postList = profileService.getAllPostsByUserId(userId);

		} catch (Exception e) {
			LOGGER.error("The user has no post", e);
			throw(e);
		} 

		return postList;


	}

	@RequestMapping(method = RequestMethod.GET, value = "/showRecentPosts")
	public @ResponseBody List<Post> showRecentPosts() throws Exception {

		List<Post> postList;
		try {
			postList = profileService.showRecentPosts();

		} catch (Exception e) {
			throw(e);
		} 

		return postList;


	}

	@RequestMapping(method = RequestMethod.GET, value = "/getPostByPostId")
	public @ResponseBody Post getPostByPostId(int postId) throws Exception {

		Post post;
		try {
			post = profileService.getPostById(postId);

		} catch (Exception e) {
			throw(e);
		} 

		return post;


	}

	@RequestMapping(method = RequestMethod.GET, value = "/post")
	public @ResponseBody int post(int userId, int postType, String postContent, String tags, int locationId, String locationName) throws Exception {

		try {
			return profileService.post(userId, postType, postContent, tags, locationId, locationName);


		} catch (Exception e) {
			return -1;
		} 



	}

	@RequestMapping(method = RequestMethod.GET, value = "/emailAvailable")
	public @ResponseBody boolean emailAvailable(String email) throws Exception {

		boolean available;
		try {
			available = registrationService.emailAvailable(email);

		} catch (Exception e) {
			LOGGER.error("The user has no post", e);
			throw(e);
		} 

		return available;


	}

	@RequestMapping(method = RequestMethod.GET, value = "/usernameAvailable")
	public @ResponseBody boolean usernameAvailable(String username) throws Exception {

		boolean available;
		try {
			available = registrationService.usernameAvailable(username);

		} catch (Exception e) {
			LOGGER.error("The user has no post", e);
			throw(e);
		} 
		return available;		
	}


	@RequestMapping(method = RequestMethod.GET, value = "/commentOnPost")
	public @ResponseBody int commentOnPost(String commentContent, int userId, int postId) throws Exception {

		try {
			return profileService.commentOn(commentContent, userId, postId);


		} catch (Exception e) {
			return -1;
		} 

	}

	@RequestMapping(method = RequestMethod.GET, value = "/deleteComment")
	public @ResponseBody boolean deleteComment(int commentId){
		return profileService.deleteComment(commentId);
	}
	
	@RequestMapping(method = RequestMethod.GET, value = "/deletePost")
	public @ResponseBody boolean deletePost(int postId){
		return profileService.deletePost(postId);
	}
	
	@RequestMapping(method = RequestMethod.GET, value = "/removeDiamond")
	public @ResponseBody boolean removeDiamond(int postId, int userId){
		return profileService.removeDiamond(postId, userId);
	}
	
	@RequestMapping(method = RequestMethod.GET, value = "/removeStar")
	public @ResponseBody boolean removeStar(int commentId){
		return profileService.removeStar(commentId);
	}

	@RequestMapping(method = RequestMethod.GET, value = "/reportOn")
	public @ResponseBody int reportOn(int contentType, int contentId, int reporterId, int reportedId) throws Exception {

		try {
			return reportService.reportOn(contentType, contentId, reporterId, reportedId);


		} catch (Exception e) {
			return -1;
		} 

	}

	@RequestMapping(method = RequestMethod.GET, value = "/giveStar")
	public @ResponseBody int commentOnPost(int commentId) throws Exception {

		try {
			profileService.giveStar(commentId);;
			return 1;

		} catch (Exception e) {
			return -1;
		} 

	}

	@RequestMapping(method = RequestMethod.GET, value = "/getCommentsOfPost")
	public @ResponseBody List<Comment> getCommentsOfPost(int postId) throws Exception {

		try {
			return profileService.getCommentsOfPost(postId);

		} catch (Exception e) {
			return null;
		} 

	}

	@RequestMapping(method = RequestMethod.GET, value = "/giveDiamond")
	public @ResponseBody int giveDiamond(int postId, int userId) throws Exception {

		try {
			profileService.giveDiamond(postId, userId);
			return 1;

		} catch (Exception e) {
			return -1;
		} 

	}

	@RequestMapping(method = RequestMethod.GET, value = "/getUserById")
	public @ResponseBody User getUserById(int userId) throws Exception {

		try {
			return profileService.getUserById(userId);

		} catch (Exception e) {
			return null;
		} 

	}

	@RequestMapping(method = RequestMethod.GET, value = "/updateBio")
	public @ResponseBody int updateBio(int userId, String bio) throws Exception {

		return profileService.updateBio(userId, bio);
	}

	@RequestMapping(method = RequestMethod.GET, value = "/changeProfilePic")
	public @ResponseBody int changeProfilePic(int userId, String profilePic) throws Exception {

		return profileService.changeProfilePic(userId, profilePic);
	}

	@RequestMapping(method = RequestMethod.GET, value = "/isPostDiamonded")
	public @ResponseBody boolean isPostDiamonded(int userId, int postId) throws Exception {
		return profileService.isPostDiamonded(userId, postId);
	}

	@RequestMapping(method = RequestMethod.GET, value = "/recommend")
	public @ResponseBody List<Post> isPostDiamonded(int userId) throws Exception {
		return UserRelation.recommend(userId);
	}

}